home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d20 / pvert.arc / PRSEADDR.C < prev    next >
C/C++ Source or Header  |  1992-01-15  |  5KB  |  188 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "addr.h"
  5.  
  6.  
  7. extern char *  rstrip (char *);
  8. extern char *  lstrip (char *);
  9. extern char *  skip_white (char *p);
  10. extern char *  skip_nonwhite (char *p);
  11. extern char *  to_delim (char *p, char *delim);
  12. extern char *  assign (char *s,char *p);
  13.  
  14.  
  15.  
  16. int  parse_addr (char **p, ADDR *r,ADDR *rr) {
  17.  
  18.     /* Tries to parse a string for a valid FTN addresss.
  19.        I say "tries" because it attempts to allow incomplete addresses
  20.        without getting itself confused.
  21.        p=pointer-to-pointer to string to parse
  22.        r=pointer to address structure to place parsed address in */
  23.  
  24.     char *domain,*zone,*net,*node,*point,*temp,*tcr,*tnum,*tcp,*start;
  25.     char lastdelim = 0;
  26.  
  27.  
  28.     r->domain = domain = zone = net = node = point = temp = NULL;
  29.     if(!*p || !**p) return -1;
  30.     *p = skip_white(*p);
  31.     start = *p;
  32.  
  33.     do {
  34.         temp = *p;
  35.         *p = to_delim(*p,"#:/.@\r\t ");
  36.         switch((int) **p) {
  37.             case '\r':
  38.             case '\0':
  39.             case ' ':
  40.             case '\t':  if(lastdelim == '.') point = temp;
  41.                         else if(lastdelim == '@') domain = temp;
  42.                         else node = temp;
  43.                         goto BreakOut;
  44.             case '#':   domain = temp;
  45.                         if(lastdelim == '.') {  /* handle fidonet.org */
  46.                             domain = start;
  47.                             point = NULL;
  48.                         }
  49.                         break;
  50.             case ':':   zone = temp;
  51.                         break;
  52.             case '/':   net = temp;
  53.                         break;
  54.             case '@':   if(lastdelim == '.') point = temp;
  55.                         else node = temp;
  56.                         break;
  57.             case '.':   if(lastdelim != '@') node = temp;
  58.                         else {
  59.                             *p = skip_nonwhite(*p); /* end this farce */
  60.                             goto BreakOut;
  61.                         }
  62.                         break;
  63.         }
  64.         lastdelim = **p;
  65.         (*p)++;     /* Skip delimiter */
  66.     } while(*p && **p);
  67.  
  68. BreakOut:
  69.  
  70.     if(!zone && !net && !point && !domain) {
  71.         if(!node || (!atoi(node) && *node != '0')) return -1;
  72.     }
  73.  
  74.     if(domain) {
  75.         lstrip(domain);
  76.         temp = strchr(domain,' ');
  77.         if(temp) *temp = 0;
  78.         tnum = strchr(domain,'#');
  79.         if(tnum) *tnum = 0;
  80.         tcr = strchr(domain,'\r');
  81.         if(tcr) *tcr = 0;
  82.         tcp = strchr(domain,'.');
  83.         if(tcp) *tcp = 0;
  84.         rstrip(domain);
  85.         if(*domain) {
  86.             r->domain = strdup(domain);
  87.         }
  88.         if(temp) *temp = ' ';
  89.         if(tcr) *tcr = '\r';
  90.         if(tnum) *tnum = '#';
  91.         if(tcp) *tcp = '.';
  92.     }
  93.     if(zone) r->zone = atoi(zone);
  94.     else r->zone = 0;
  95.     if(net) r->net = atoi(net);
  96.     else r->net = 0;
  97.     if(node) r->node = atoi(node);
  98.     else r->node = 0;
  99.     if(point) r->point = atoi(point);
  100.     else r->point = 0;
  101.  
  102. Again:
  103.  
  104.     if(!r->zone || !r->net || !node || !r->domain) {
  105.         if(rr) {
  106.             guess_rest(r,rr);
  107.             rr = NULL;
  108.             goto Again;
  109.         }
  110.         else return -1;
  111.     }
  112.  
  113.     return 0;
  114. }
  115.  
  116.  
  117.  
  118.  
  119. int  guess_rest (ADDR *r, ADDR *m) {
  120.  
  121.     /* Makes primitive attempt to fill in missing fields of address
  122.        r=pointer to address structure to complete
  123.        m=pointer to first address in list to find missing info in */
  124.  
  125.     ADDR *temp;
  126.  
  127.  
  128.     if(!r->net) r->net = m->net;  /* always assume primary address' net */
  129.  
  130.     if(!r->zone) {
  131.         temp = m;
  132.         r->zone = m->zone;        /* start assuming primary address' zone */
  133.         while(temp) {
  134.             if(temp->net == r->net) { /* unless we get a net match */
  135.                 r->zone = temp->zone;
  136.                 break;
  137.             }
  138.             temp = temp->next;
  139.         }
  140.     }
  141.  
  142.     if(!r->domain) {
  143.         r->domain = strdup(m->domain);  /* start assuming primary domain */
  144.         temp = m;
  145.         while(temp) {
  146.             if(temp->zone == r->zone) {   /* unless we get zone match */
  147.                 r->domain = assign(r->domain,temp->domain);
  148.             }
  149.             if(temp->net == r->net) break;    /* if we get a net match, break */
  150.             temp = temp->next;
  151.         }
  152.     }
  153.  
  154.     return 0;
  155. }
  156.  
  157.  
  158.  
  159.  
  160. ADDR *  best_guess (ADDR *r,ADDR *m) {
  161.  
  162.     /* take our best guess as to who we should be when talking to node r
  163.        m is list of addresses from which to choose */
  164.  
  165.     ADDR *temp,*ret = NULL;
  166.  
  167.  
  168.     if(!r) return m;
  169.  
  170.     temp = m;
  171.     while(temp) {
  172.         if(r->domain && temp->domain && !stricmp(temp->domain,r->domain)) {
  173.             if(!ret) ret = temp;         /* at least domains will match */
  174.             if(temp->zone == r->zone) {
  175.                 if(ret->zone != r->zone) ret = temp;  /* zones too */
  176.                 if(temp->net == r->net) {             /* nets match! */
  177.                     ret = temp;
  178.                     break;             /* close as we're likely to get */
  179.                 }
  180.             }
  181.         }
  182.         temp = temp->next;
  183.     }
  184.  
  185.     if(ret) return ret;
  186.     else return m;
  187. }
  188.